/**
 */
package fUML.Semantics.Activities.ExtraStructuredActivities;

import fUML.Semantics.Actions.BasicActions.ActionActivation;

import fUML.Syntax.Activities.ExtraStructuredActivities.ExpansionNode;

import org.eclipse.emf.common.util.EList;

/**
 * <!-- begin-user-doc -->
 * A representation of the model object '<em><b>Expansion Region Activation</b></em>'.
 * <!-- end-user-doc -->
 *
 * <!-- begin-model-doc -->
 * An expansion region activation is an action activation for a node that is an
 *                 expansion region.
 *  [Note that even though an expansion region is a
 *                 structured activity node, an expansion region activation is not a structured
 *                 activity activation because of the special nature of expansion region
 *               behavior.]
 * <!-- end-model-doc -->
 *
 * <p>
 * The following features are supported:
 * <ul>
 *   <li>{@link fUML.Semantics.Activities.ExtraStructuredActivities.ExpansionRegionActivation#getInputTokens <em>Input Tokens</em>}</li>
 *   <li>{@link fUML.Semantics.Activities.ExtraStructuredActivities.ExpansionRegionActivation#getInputExpansionTokens <em>Input Expansion Tokens</em>}</li>
 *   <li>{@link fUML.Semantics.Activities.ExtraStructuredActivities.ExpansionRegionActivation#getActivationGroups <em>Activation Groups</em>}</li>
 * </ul>
 * </p>
 *
 * @see fUML.Semantics.Activities.ExtraStructuredActivities.ExtraStructuredActivitiesPackage#getExpansionRegionActivation()
 * @model
 * @generated
 */
public interface ExpansionRegionActivation extends ActionActivation {
	/**
	 * Returns the value of the '<em><b>Input Tokens</b></em>' containment reference list.
	 * The list contents are of type {@link fUML.Semantics.Activities.ExtraStructuredActivities.TokenSet}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * The tokens taken from each of the input pin activations for this expansion
	 *                   region activation. These are preserved for initializing the region inputs of each
	 *                   of the activation groups.
	 * <!-- end-model-doc -->
	 * @return the value of the '<em>Input Tokens</em>' containment reference list.
	 * @see fUML.Semantics.Activities.ExtraStructuredActivities.ExtraStructuredActivitiesPackage#getExpansionRegionActivation_InputTokens()
	 * @model containment="true" ordered="false"
	 * @generated
	 */
	EList<TokenSet> getInputTokens();

	/**
	 * Returns the value of the '<em><b>Input Expansion Tokens</b></em>' containment reference list.
	 * The list contents are of type {@link fUML.Semantics.Activities.ExtraStructuredActivities.TokenSet}.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * The tokens taken from each of the input expansion node activations for this
	 *                   expansion region activation. These are preserved for initializing the group input
	 *                   of each of the activation groups.
	 * <!-- end-model-doc -->
	 * @return the value of the '<em>Input Expansion Tokens</em>' containment reference list.
	 * @see fUML.Semantics.Activities.ExtraStructuredActivities.ExtraStructuredActivitiesPackage#getExpansionRegionActivation_InputExpansionTokens()
	 * @model containment="true" required="true" ordered="false"
	 * @generated
	 */
	EList<TokenSet> getInputExpansionTokens();

	/**
	 * Returns the value of the '<em><b>Activation Groups</b></em>' containment reference list.
	 * The list contents are of type {@link fUML.Semantics.Activities.ExtraStructuredActivities.ExpansionActivationGroup}.
	 * It is bidirectional and its opposite is '{@link fUML.Semantics.Activities.ExtraStructuredActivities.ExpansionActivationGroup#getRegionActivation <em>Region Activation</em>}'.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * The set of expansion activation groups for this expansion region activation.
	 *                   One activation group is created corresponding to each token held by the first
	 *                   input expansion node activation for the expansion region.
	 * <!-- end-model-doc -->
	 * @return the value of the '<em>Activation Groups</em>' containment reference list.
	 * @see fUML.Semantics.Activities.ExtraStructuredActivities.ExtraStructuredActivitiesPackage#getExpansionRegionActivation_ActivationGroups()
	 * @see fUML.Semantics.Activities.ExtraStructuredActivities.ExpansionActivationGroup#getRegionActivation
	 * @model opposite="regionActivation" containment="true" ordered="false"
	 * @generated
	 */
	EList<ExpansionActivationGroup> getActivationGroups();

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Create a number of expansion region activation groups equal to the number
	 *                   of values expanded in the region, 
	 *  // setting the region inputs and group
	 *                   inputs for each group.
	 *  // Run the body of the region in each group,
	 *                   either iteratively or in parallel.
	 *  // Add the outputs of each activation
	 *                   group to the corresonding output expansion node activations.
	 *  
	 *                   ExpansionRegion region = (ExpansionRegion)this.node;
	 *  InputPinList
	 *                   inputPins = region.input;
	 *  ExpansionNodeList inputElements =
	 *                   region.inputElement;
	 *  ExpansionNodeList outputElements =
	 *                   region.outputElement;
	 *  
	 *  int n =
	 *                   this.inputExpansionTokens.getValue(0).tokens.size();
	 *  int k = 1;
	 *                   while (k <= n) {
	 *  ExpansionActivationGroup activationGroup = new
	 *                   ExpansionActivationGroup();
	 *  activationGroup.regionActivation =
	 *                   this;
	 *  activationGroup.index = k;
	 *  
	 *  int j = 1;
	 *                   while (j <= inputPins.size()) {
	 *  OutputPinActivation regionInput =
	 *                   new OutputPinActivation();
	 *  regionInput.run();
	 *                   activationGroup.regionInputs.addValue(regionInput);
	 *  j = j + 1;
	 *                   }
	 *  
	 *  j = 1;
	 *  while (j <= inputElements.size())
	 *                   {
	 *  OutputPinActivation groupInput = new OutputPinActivation();
	 *                   groupInput.run();
	 *                   activationGroup.groupInputs.addValue(groupInput);
	 *  j = j + 1;
	 *                   }
	 *  
	 *  j = 1;
	 *  while (j <= outputElements.size())
	 *                   {
	 *  OutputPinActivation groupOutput = new OutputPinActivation();
	 *                   groupOutput.run();
	 *  activationGroup.groupOutputs.addValue(new
	 *                   OutputPinActivation());
	 *  j = j + 1;
	 *  }
	 *  
	 *                   activationGroup.createNodeActivations(region.node);
	 *                   activationGroup.createEdgeInstances(region.edge);
	 *                   this.activationGroups.addValue(activationGroup);
	 *  
	 *  k = k +
	 *                   1;
	 *  }
	 *  
	 *  ExpansionActivationGroupList activationGroups =
	 *                   this.activationGroups;
	 *  
	 *  if (region.mode ==
	 *                   ExpansionKind.iterative) {
	 *  Debug.println("[doStructuredActivity]
	 *                   Expansion mode = iterative");
	 *  for (int i = 0; i <
	 *                   activationGroups.size(); i++) {
	 *  ExpansionActivationGroup activationGroup
	 *                   = activationGroups.getValue(i);
	 *  this.runGroup(activationGroup);
	 *                   }
	 *  }
	 *  else if (region.mode == ExpansionKind.parallel) {
	 *                   Debug.println("[doStructuredActivity] Expansion mode = parallel");
	 *  // ***
	 *                   Activate all groups concurrently. ***
	 *  for (Iterator i =
	 *                   activationGroups.iterator(); i.hasNext();) {
	 *  ExpansionActivationGroup
	 *                   activationGroup = (ExpansionActivationGroup)i.next();
	 *                   this.runGroup(activationGroup);
	 *  }
	 *  }
	 *  
	 *  for (int
	 *                   i = 0; i < activationGroups.size(); i++) {
	 *                   ExpansionActivationGroup activationGroup = activationGroups.getValue(i);
	 *                   OutputPinActivationList groupOutputs = activationGroup.groupOutputs;
	 *  for
	 *                   (int j = 0; j < groupOutputs.size(); j++) {
	 *  OutputPinActivation
	 *                   groupOutput = groupOutputs.getValue(j);
	 *  ExpansionNode outputElement =
	 *                   outputElements.getValue(j);
	 *                   this.getExpansionNodeActivation(outputElement).addTokens(groupOutput.takeTokens());
	 *                   }
	 *  }
	 *  
	 *  
	 *  
	 * <!-- end-model-doc -->
	 * @model
	 * @generated
	 */
	void doStructuredActivity();

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Set up the inputs for the group with the given index, run the group and
	 *                   then fire the group outputs.
	 *  
	 *  Debug.println("[runGroup]
	 *                   groupInput[0] = " +
	 *                   this.inputExpansionTokens.getValue(0).tokens.getValue(activationGroup.index-1).getValue());
	 *                   
	 *  TokenSetList inputTokens = this.inputTokens;
	 *  for (int j = 0; j
	 *                   < inputTokens.size(); j++) {
	 *  TokenSet tokenSet =
	 *                   inputTokens.getValue(j);
	 *  OutputPinActivation regionInput =
	 *                   activationGroup.regionInputs.getValue(j);
	 *                   regionInput.clearTokens();
	 *                   regionInput.addTokens(tokenSet.tokens);
	 *                   regionInput.sendUnofferedTokens();
	 *  }
	 *  
	 *  TokenSetList
	 *                   inputExpansionTokens = this.inputExpansionTokens;
	 *  for (int j = 0; j
	 *                   < inputExpansionTokens.size(); j++) {
	 *  TokenSet tokenSet =
	 *                   inputExpansionTokens.getValue(j);
	 *  OutputPinActivation groupInput =
	 *                   activationGroup.groupInputs.getValue(j);
	 *                   groupInput.clearTokens();
	 *                   groupInput.addToken(tokenSet.tokens.getValue(activationGroup.index-1));
	 *                   groupInput.sendUnofferedTokens();
	 *  }
	 *  
	 *                   activationGroup.run(activationGroup.nodeActivations);
	 *  
	 *                   OutputPinActivationList groupOutputs = activationGroup.groupOutputs;
	 *  for
	 *                   (int i = 0; i < groupOutputs.size(); i++) {
	 *  OutputPinActivation
	 *                   groupOutput = groupOutputs.getValue(i);
	 *                   groupOutput.fire(groupOutput.takeOfferedTokens());
	 *  }
	 *  
	 *                   activationGroup.terminateAll();
	 *  
	 * <!-- end-model-doc -->
	 * @model activationGroupRequired="true" activationGroupOrdered="false"
	 * @generated
	 */
	void runGroup(ExpansionActivationGroup activationGroup);

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Return the expansion node activation corresponding to the given expansion
	 *                   node, in the context of the activity node activation group this expansion region
	 *                   activation is in.
	 *  // [Note: Expansion regions do not own their expansion
	 *                   nodes. Instead, they are own as object nodes by the enclosing activity or group.
	 *                   
	 *  // Therefore, they will already be activated along with their expansion
	 *                   region.]
	 *  
	 *  return
	 *                   (ExpansionNodeActivation)(this.group.getNodeActivation(node));
	 *  
	 *                 
	 * <!-- end-model-doc -->
	 * @model required="true" ordered="false" nodeRequired="true" nodeOrdered="false"
	 * @generated
	 */
	ExpansionNodeActivation getExpansionNodeActivation(ExpansionNode node);

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * <!-- begin-model-doc -->
	 * // Return the number of values on the first input expansion node of the
	 *                   expansion region of this activation.
	 *  // (The region is required to have
	 *                   at least one input expansion node.)
	 *  
	 *  ExpansionRegion region =
	 *                   (ExpansionRegion)(this.node);
	 *  
	 *  return
	 *                   this.getExpansionNodeActivation(region.inputElement.getValue(0)).countOfferedValues();
	 *                 
	 * <!-- end-model-doc -->
	 * @model required="true" ordered="false"
	 * @generated
	 */
	int numberOfValues();

} // ExpansionRegionActivation
